'use strict';

const Service = require('egg').Service;
const fs = require('fs');
const path = require('path');
const sendToWormhole = require('stream-wormhole');

class FileService extends Service {
  /**
   * 新增文件或文件夹
   * @param { Object } query 请求参数
   * @param { String } name   存储的文件名
   */
  async addNewFile(query, name) {
    // 开始新增数据
    const resp = await this.ctx.model.File.create({
      name,
      originName: query.name,
      ext: query.ext,
      path: query.path,
      size: query.size,
    });
    return resp;
  }

  async getFileByName(name) {
    return await this.ctx.model.File.findOne({
      where: { name },
      raw: true,
    });
  }

  /**
   * 上传文件流
   * @param { Stream } stream 文件流
   * @param { String } name   存储的文件名
   */
  async uploadFile(stream, name) {
    // 获取文件名
    const { filename } = stream;
    // 文件扩展名
    const fileExt = filename.split('.')[1];
    // 获取当前上传的文件夹路径
    const uploadPath = path.join(this.config.filePath, `${name}.${fileExt}`);

    const result = await new Promise((resolve, reject) => {
      // 文件流
      const fileStream = fs.createWriteStream(uploadPath);
      // 开始处理流
      stream.pipe(fileStream);
      // 是否错误标志
      let errFlag;
      // 监听写入错误方法
      fileStream.on('error', err => {
        errFlag = true;
        sendToWormhole(stream);
        fileStream.destroy();
        reject(err);
      });
      // 监听写入成功
      fileStream.on('finish', async () => {
        if (errFlag) return;
        resolve({ filename, path: uploadPath, name: stream.fields.name });
      });
    });
    return result;
  }
}

module.exports = FileService;
